package com.jianz.campus_markets.filter;
import com.jianz.campus_markets.domain.entity.SensitiveWord;
import com.jianz.campus_markets.mapper.SensitiveWordMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.CharUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * {@code @Description}:当前类用于鉴定敏感词，组件初始化后会从数据库获取管理员添加的敏感词
 * 这些词都加载在内存中，后期可以优化。
 */
@Slf4j
@Component
public class SensitiveFilter {
        @Autowired
        SensitiveWordMapper sensitiveWordMapper;
        private static final String REPLACEMENT = "***";
        private TrieNode rootNode = new TrieNode();
        @PostConstruct
        public void init(){
                rootNode = new TrieNode();
                List<SensitiveWord> sensitiveWords = sensitiveWordMapper.selectPage();
                for (SensitiveWord sensitiveWord : sensitiveWords) {
//                        log.info(sensitiveWord.getWord());
                        this.addKeyword(sensitiveWord.getWord());
                }
        }
        private void addKeyword(String keyword){
                TrieNode tempNode = rootNode;
                for (int i = 0; i <keyword.length() ; i++) {
                        char c = keyword.charAt(i);
                        TrieNode subNode = tempNode.getSubNode(c);
                        if(subNode==null){

                                subNode = new TrieNode();
                                tempNode.addSubNode(c,subNode);
                        }
                        tempNode = subNode;
                        if(i==keyword.length()-1){
                                tempNode.setKeywordEnd(true);
                        }
                }
        }
        public String filter(String text){
                if(StringUtils.isBlank(text)){
                        return null;
                }
                TrieNode tempNode = rootNode;
                int begin = 0;
                int position = 0;
                StringBuilder sb = new StringBuilder();
                while(position<text.length()){
                        char c = text.charAt(position);
                        if(isSymbol(c)){
                                if(tempNode==rootNode){
                                        sb.append(c);
                                        begin++;
                                }
                                position++;
                                continue;
                        }
                        tempNode = tempNode.getSubNode(c);
                        if(tempNode==null){
                                sb.append(text.charAt(begin));
                                position = ++begin;
                                tempNode = rootNode;
                        }else if(tempNode.isKeywordEnd()){
                                sb.append(REPLACEMENT);
                                begin = ++position;
                                tempNode = rootNode;
                        }else {
                                position++;
                        }
                }
                sb.append(text.substring(begin));
                return sb.toString();
        }
        private boolean isSymbol(Character c){
                return !CharUtils.isAsciiAlphanumeric(c) && (c < 0x2E80 || c > 0x9FFF);
        }
        public boolean isSensitive(String text){
                if(StringUtils.isBlank(text)){
                        return false;
                }
                TrieNode tempNode = rootNode;
                int begin = 0;
                int position = 0;
                StringBuilder sb = new StringBuilder();
                while(position<text.length()){
                        char c = text.charAt(position);
                        if(isSymbol(c)){
                                if(tempNode==rootNode){
                                        sb.append(c);
                                        begin++;
                                }
                                position++;
                                continue;
                        }
                        tempNode = tempNode.getSubNode(c);
                        if(tempNode==null){
                                sb.append(text.charAt(begin));
                                position = ++begin;
                                tempNode = rootNode;
                        }else if(tempNode.isKeywordEnd()){
                                System.out.println("gql-----");

                                return true;
                        }else {
                                position++;
                        }
                }
                return false;
        }
}
